home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / dkbuts.zip / DUMP2I24.C < prev    next >
C/C++ Source or Header  |  1991-05-16  |  15KB  |  449 lines

  1. /********************************************************************/
  2. /*                                                                  */
  3. /* DumpToIFF24: Convert DKB/QRT Dump file to IFF 24 bit format.     */
  4. /*                                                                  */
  5. /* This can be used when converting output from the DKB raytracer to*/
  6. /* HAM-E format.                                                    */
  7. /*                                                                  */
  8. /* Usage:                                                           */
  9. /*   dump2i24 <dump-file> <iff-file>                                */
  10. /*                                                                  */
  11. /* History:                                                         */
  12. /*  17-Oct-90: First version.                                       */
  13. /*             Helge E. Rasmussen (her@compel.dk)                   */
  14. /*                                                                  */
  15. /*  25-Apr-91: 2nd version - somewhat ANSI-ized                     */
  16. /*             David K. Buck and Aaron A. Collins                   */
  17. /*                                                                  */
  18. /********************************************************************/
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22.  
  23. #ifndef lint
  24. static char    *RCS_Version = 
  25.     "@(#)dump2i24.c  v. 1.0 17-Oct-90 by Helge E. Rasmussen";
  26. #endif
  27.  
  28. unsigned char *PutDump(unsigned char *, long);
  29. unsigned char *PutRun(unsigned char *, long, long);
  30. long PackRow(unsigned char *, unsigned char **, long);
  31. void Plot_Pixel(unsigned char **, long, long);
  32. void Write_String(FILE *, char *, long);
  33. void Write_Byte(FILE *, long);
  34. void Write_Word(FILE *, long);
  35. void Write_Long(FILE *, long);
  36. void Convert_Dump_To_Iff24(FILE *, FILE *);
  37.  
  38. #define USAGE "Usage: dump2i24 <dump_file> <iff_file>"
  39.  
  40. #define DEPTH        24                /* Depth of Amiga rgb24 image   */
  41.  
  42. #define BMHDsize    20L                /* Size of BMHD chunk           */
  43.  
  44. int  Compress       = 1;            /* compress image?              */
  45.  
  46.  
  47. /************************ run length encoding from Amiga RKM *****************/
  48.  
  49. unsigned char  *Dst_Ptr, Dst_Buf[BUFSIZ];
  50. long             Dst_Size;
  51. char            Rle_Buf[256];
  52.  
  53. #define DUMP                0   /* list of different bytes              */
  54. #define RUN                    1   /* single run of bytes                  */
  55. #define MinRun                3   /* shortest allowed run                 */
  56. #define MaxRun                128 /* longest run (length is signed char)  */
  57. #define    MaxDat                128 /* longest block of unencoded data      */
  58. #define PutByte(dst,c,size)    { *dst++ = (char)(c); ++size; }
  59. #define OutDump(dst,nn)        dst = PutDump(dst,nn);
  60. #define OutRun(dst,nn,cc)    dst = PutRun(dst,nn,cc);
  61.  
  62.  
  63. unsigned char  *PutDump(Dst_Ptr, nn)
  64. unsigned char  *Dst_Ptr;
  65. long             nn;
  66. /************************************************************************/
  67. /*                                                                      */
  68. /*                                                                      */
  69. /************************************************************************/
  70. {
  71.     long i;
  72.  
  73.     PutByte(Dst_Ptr, nn - 1, Dst_Size);
  74.     for (i = 0; i < nn; i++) PutByte(Dst_Ptr, Rle_Buf[i], Dst_Size);
  75.     
  76.     return (Dst_Ptr);
  77.     
  78. } /* PutDump */
  79.  
  80. unsigned char  *PutRun(Dst_Ptr, nn, cc)
  81. unsigned char  *Dst_Ptr;
  82. long             nn, cc;
  83. /************************************************************************/
  84. /*                                                                      */
  85. /*                                                                      */
  86. /************************************************************************/
  87. {
  88.     PutByte(Dst_Ptr, -(nn - 1), Dst_Size);
  89.     PutByte(Dst_Ptr, cc, Dst_Size);
  90.     
  91.     return (Dst_Ptr);
  92.  
  93. } /* PutRun */
  94.  
  95. long  PackRow(Source, pDst, RowSize)
  96. unsigned char *Source; 
  97. unsigned char **pDst;
  98. long           RowSize;
  99. /************************************************************************/
  100. /*                                                                      */
  101. /* PackRow - pack a row of data using Amiga IFF RLE                     */
  102. /*                                                                      */
  103. /************************************************************************/
  104. {
  105.     unsigned char   *Dst_Ptr;
  106.     char            c; 
  107.     char            lastc;
  108.     long             mode   = DUMP; 
  109.     long             rstart = 0;    /* Buf index current run starts */
  110.     long                nBuf;        /* number of chars in Buf */
  111.  
  112.     Dst_Ptr   = *pDst;
  113.  
  114.     Dst_Size = 0;
  115.     Rle_Buf[0] = lastc = c = *Source++;
  116.     nBuf = 1;
  117.     RowSize--;
  118.  
  119.     for (; RowSize > 0; --RowSize) {
  120.  
  121.         Rle_Buf[nBuf++] = c = *Source++;
  122.  
  123.         switch (mode) {
  124.  
  125.             case DUMP:
  126.                 if (nBuf > MaxDat) {
  127.                     OutDump(Dst_Ptr, nBuf - 1);
  128.                     Rle_Buf[0] = c;
  129.                     nBuf   = 1;
  130.                     rstart = 0;
  131.                     break;
  132.                 }
  133.                 if (c == lastc) {
  134.                     if (nBuf - rstart >= MinRun) {
  135.                         if (rstart > 0) OutDump(Dst_Ptr, rstart);
  136.                            mode = RUN;
  137.                     }
  138.                     else if (rstart == 0)
  139.                     mode = RUN;
  140.                 }
  141.                 else
  142.                 rstart = nBuf - 1;
  143.                 break;
  144.  
  145.             case RUN:
  146.                 if ((c != lastc) || (nBuf - rstart > MaxRun)) {
  147.                     OutRun(Dst_Ptr, (nBuf - 1) - rstart, lastc);
  148.                     Rle_Buf[0] = c;
  149.                     nBuf   = 1;
  150.                     rstart = 0;
  151.                     mode   = DUMP;
  152.                 }
  153.                 break;
  154.  
  155.         } /* switch */
  156.  
  157.         lastc = c;
  158.  
  159.     } /* for */
  160.  
  161.     switch (mode) {
  162.         case DUMP:
  163.             OutDump(Dst_Ptr, nBuf);
  164.             break;
  165.         case RUN:
  166.             OutRun(Dst_Ptr, nBuf - rstart, lastc);
  167.             break;
  168.     } /* switch */
  169.  
  170.     *pDst   = Dst_Ptr;
  171.  
  172.     return(Dst_Size);
  173.  
  174. } /* PackRow */
  175.  
  176. /******************* end of RKM RL encoding routines **********************/
  177.  
  178.  
  179. void Plot_Pixel(Planes, Column, Color)
  180. unsigned char *Planes[];
  181. long  Column;
  182. long  Color;
  183. /************************************************************************/
  184. /*                                                                      */
  185. /* Plot 'Color' in the bitplanes at the position given by 'Column'      */
  186. /*                                                                      */
  187. /************************************************************************/
  188. {
  189.     register long           Bit;
  190.     register unsigned char Shifted_Bit = (unsigned char)(1 << (7 - (Column % 8)));
  191.     register long           Array_Offset = Column / 8;
  192.     register long           Plane;
  193.  
  194.     for (Plane = 0; Color && (Plane < DEPTH); Plane++) {
  195.     
  196.         Bit = Color & 1;
  197.         Color >>= 1;
  198.         
  199.         if (Bit) *(Planes[Plane] + Array_Offset) |= Shifted_Bit;
  200.     
  201.     } /* for */
  202.     
  203. } /* Plot_Pixel */
  204.  
  205. void Write_String(Stream, String, Length)
  206. FILE    *Stream;
  207. char    *String;
  208. long     Length;
  209. /************************************************************************/
  210. /*                                                                      */
  211. /*                                                                      */
  212. /************************************************************************/
  213. {
  214.     fwrite(String, 1, (unsigned int)Length, Stream);
  215. } /* Write_String */
  216.  
  217. void Write_Byte(Stream, Value)
  218. FILE    *Stream;
  219. long     Value;
  220. /************************************************************************/
  221. /*                                                                      */
  222. /*                                                                      */
  223. /************************************************************************/
  224. {
  225.     putc ((int) (Value & 0xFF), Stream); 
  226. } /* Write_Byte */
  227.  
  228. void Write_Word(Stream, Value)
  229. FILE    *Stream;
  230. long     Value;
  231. /************************************************************************/
  232. /*                                                                      */
  233. /*                                                                      */
  234. /************************************************************************/
  235. {
  236.     putc ((int) (Value>>8 & 0xFF), Stream); 
  237.     putc ((int) (Value & 0xFF), Stream); 
  238. } /* Write_Word */
  239.  
  240. void Write_Long(Stream, Value)
  241. FILE    *Stream;
  242. long    Value;
  243. /************************************************************************/
  244. /*                                                                      */
  245. /*                                                                      */
  246. /************************************************************************/
  247. {
  248.     putc ((int) (Value>>24 & 0xFF), Stream); 
  249.     putc ((int) (Value>>16 & 0xFF), Stream); 
  250.     putc ((int) (Value>>8 & 0xFF), Stream); 
  251.     putc ((int) (Value & 0xFF), Stream); 
  252.     
  253. } /* Write_Long */
  254.  
  255. void Convert_Dump_To_Iff24(Dump_Stream, Iff_Stream)
  256. FILE    *Dump_Stream;
  257. FILE    *Iff_Stream;
  258. /************************************************************************/
  259. /*                                                                      */
  260. /* Write an DKB/QRT Dumpimage from 'Dump_Stream' and write the image in */
  261. /* IFF 24-bit format on 'Iff_Stream'.                                   */
  262. /*                                                                      */
  263. /************************************************************************/
  264. {
  265.     long             Row, Col;
  266.     long             Plane;
  267.     long             i;
  268.     unsigned char   *Red, *Green, *Blue;
  269.     long             RgbVal;
  270.     long             Row_Size;    /* number of bytes in IFF row of data */
  271.     long             Length;
  272.     long             Body_Size;
  273.     long             Form_Size;
  274.     long             Pos_Form_Size; 
  275.     long             Pos_Body_Size;
  276.     unsigned char   *Planes[DEPTH];
  277.     long             Nbr_Cols, Nbr_Rows;
  278.     long             Dump_Buffer_Length;
  279.     unsigned char   *Dump_Buffer;  
  280.     long             Dump_Row;
  281.     
  282.     printf("Reading DKB/QRT Dump file.\n");
  283.     
  284.     Nbr_Cols      = getc(Dump_Stream);
  285.     Nbr_Cols     |= (getc(Dump_Stream)<<8);
  286.     Nbr_Rows      = getc(Dump_Stream);
  287.     Nbr_Rows     |= (getc(Dump_Stream)<<8);
  288.   
  289.     Row_Size = ((Nbr_Cols + 15) / 16) * 2;
  290.     
  291.     printf("Width = %d, Height = %d.\n", Nbr_Cols, Nbr_Rows);
  292.                         
  293.  
  294.  
  295.     Dump_Buffer_Length = Nbr_Cols * 3;
  296.     
  297.     Dump_Buffer = (unsigned char *) malloc((unsigned int)Dump_Buffer_Length);
  298.     if (Dump_Buffer == NULL) {
  299.         fprintf(stderr, "Couldn't allocate space for Dump file buffer\n");
  300.         fflush(stderr);
  301.         exit(1);
  302.     }
  303.     
  304.         /* Allocate memory for bit planes for one scanline. */
  305.         
  306.     for (Plane = 0; Plane < DEPTH ; Plane++) {
  307.         
  308.         Planes[Plane] = (unsigned char *)malloc((unsigned int)Row_Size);
  309.         
  310.         if (Planes[Plane] == NULL) {
  311.             fprintf(stderr, "Couldn't allocate memory for planes.\n");
  312.             exit(1);
  313.         }
  314.         
  315.     } /* for */
  316.     
  317.      
  318.     Write_String(Iff_Stream, "FORM", 4);
  319.     Pos_Form_Size = ftell(Iff_Stream);
  320.     Write_Long(Iff_Stream, 0L);      /* This value is filled out later */
  321.     
  322.     Write_String(Iff_Stream, "ILBM", 4);
  323.     Write_String(Iff_Stream, "BMHD", 4);
  324.     Write_Long(Iff_Stream, BMHDsize);
  325.  
  326.     Write_Word(Iff_Stream, Nbr_Cols);           /* Width        */
  327.     Write_Word(Iff_Stream, Nbr_Rows);           /* Height       */
  328.     Write_Word(Iff_Stream, 0);                  /* Top          */
  329.     Write_Word(Iff_Stream, 0);                  /* Left         */
  330.     Write_Byte(Iff_Stream, DEPTH);              /* Depth        */
  331.     Write_Byte(Iff_Stream, 0);                  /* Mask         */
  332.     Write_Byte(Iff_Stream, Compress);           /* Compress     */
  333.     Write_Byte(Iff_Stream, 0);                  /* Pad          */
  334.     Write_Word(Iff_Stream, 0);                  /* Transparency */
  335.     Write_Byte(Iff_Stream, 10);                 /* Aspect x     */
  336.     Write_Byte(Iff_Stream, 11);                 /* Aspect y     */
  337.     Write_Word(Iff_Stream, Nbr_Cols);           /* Page Width   */
  338.     Write_Word(Iff_Stream, Nbr_Rows);           /* Page Height  */
  339.  
  340.     Write_String(Iff_Stream, "BODY", 4);
  341.     Pos_Body_Size = ftell(Iff_Stream);
  342.     Write_Long(Iff_Stream, 0L);      /* This value is filled out later */
  343.  
  344.     Body_Size= 0;
  345.     
  346.     for (Row = 0; Row < Nbr_Rows; Row++) {
  347.  
  348.         if (Row % 50 == 0)      {  printf("%d", Row); fflush(stdout); } 
  349.         else if (Row % 10 == 0) {  printf(".");       fflush(stdout); } 
  350.         
  351.  
  352.         for (Plane = 0; Plane < DEPTH ; Plane++) {
  353.             for (i = 0; i < Row_Size; i++) Planes[Plane][i] = 0;
  354.         } /* for */
  355.         
  356.         Dump_Row = getc(Dump_Stream);
  357.         Dump_Row |= (getc(Dump_Stream)<<8);
  358.         
  359.         if (! fread(Dump_Buffer, (unsigned int)Dump_Buffer_Length, 1, Dump_Stream)) { 
  360.             fprintf(stderr, 
  361.                 "Premature end of file at line %d (%d).\n", Row, Dump_Row);
  362.             break;
  363.         } /* if */
  364.         
  365.         Red   = Dump_Buffer;
  366.         Green = Red   + Nbr_Cols;
  367.         Blue  = Green + Nbr_Cols;
  368.  
  369.         for (Col = 0; Col < Nbr_Cols; Col++) {
  370.             RgbVal  = ((*Blue++)  << 16) + 
  371.                       ((*Green++) << 8) + 
  372.                       ((*Red++));
  373.                   
  374.             Plot_Pixel(Planes, Col, RgbVal);
  375.         } /* for */
  376.         
  377.         for (Plane = 0; Plane < DEPTH ; Plane++) {
  378.             if (Compress) {
  379.                 Dst_Ptr = Dst_Buf;
  380.                 Length = PackRow(Planes[Plane], &Dst_Ptr, Row_Size);
  381.                 Write_String(Iff_Stream, Dst_Buf, Length);
  382.                 Body_Size += Length;
  383.             } else {
  384.                 Write_String(Iff_Stream, Planes[Plane], Row_Size);
  385.                 Body_Size += Row_Size;
  386.             }
  387.         } /* for */
  388.         
  389.     } /* for */
  390.     
  391.     printf("\n");
  392.  
  393.     fseek(Iff_Stream, Pos_Body_Size, 0);
  394.     Write_Long(Iff_Stream, Body_Size);
  395.     
  396.     Form_Size = Body_Size + BMHDsize + 28;
  397.     fseek(Iff_Stream, Pos_Form_Size, 0);
  398.     Write_Long(Iff_Stream, Form_Size);
  399.  
  400.     free(Dump_Buffer);
  401.     for (Plane = 0; Plane < DEPTH ; Plane++) free(Planes[Plane]);
  402.     
  403. } /* Convert_Dump_To_Iff24 */
  404.  
  405.  
  406. void main(argc, argv)
  407. int argc;
  408. char *argv[];
  409. /************************************************************************/
  410. /*                                                                      */
  411. /* Convert DKB/QRT Dump File to IFF 24 bit format.                      */
  412. /*                                                                      */
  413. /************************************************************************/
  414. {
  415.     FILE *Dump_Stream;
  416.     char *Dump_Filename;
  417.     FILE *Iff_Stream;
  418.     char *Iff_Filename;
  419.  
  420.     if (argc != 3) {
  421.        fprintf(stderr, "%s\n", USAGE);
  422.        exit(1);
  423.     } /* if */
  424.     
  425.     Dump_Filename = argv[1];
  426.     Iff_Filename = argv[2];
  427.     
  428.     Dump_Stream = fopen(Dump_Filename, "rb");
  429.     if (Dump_Stream == NULL) {
  430.         fprintf(stderr, "Error opening '%s' for reading.\n", Dump_Filename);
  431.         exit(1);
  432.     } /* if */
  433.     
  434.     Iff_Stream = fopen(Iff_Filename, "wb");
  435.     if (Iff_Stream == NULL) {
  436.         fprintf(stderr, "Error opening '%s' for writing\n", Iff_Filename);
  437.         exit(1);
  438.     } /* if */
  439.         
  440.     Convert_Dump_To_Iff24(Dump_Stream, Iff_Stream);
  441.     
  442.     fclose(Dump_Stream);
  443.     fclose(Iff_Stream);
  444.     
  445.     exit(0);
  446.     
  447. } /* main */
  448.  
  449.